package com.teufandsub.socialproximity.gui;

import java.util.AbstractMap.SimpleEntry;

import org.json.JSONObject;

import android.content.Context;
import android.content.Intent;
import android.os.AsyncTask;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.WindowManager;
import android.view.inputmethod.InputMethodManager;
import android.widget.Button;
import android.widget.EditText;
import android.widget.ImageButton;
import android.widget.ListView;
import android.widget.Toast;

import com.teufandsub.socialproximity.R;
import com.teufandsub.socialproximity.controller.Constants;
import com.teufandsub.socialproximity.controller.Controller;
import com.teufandsub.socialproximity.controller.Utils;
import com.teufandsub.socialproximity.logic.ChatConversation;
import com.teufandsub.socialproximity.logic.Friend;
import com.teufandsub.socialproximity.logic.Message;
import com.teufandsub.socialproximity.logic.User;

/**
 * @author Bastien Mathias <bastienmathias@gmail.com>
 * @author Antoine Teuf <antoine.teuf@gmail.com>
 * @version 1.0
 * @since 2013-05-22
 * 
 * The personal Chatting Activity with someone.
 */

public class ChattingActivity extends SocialProxActivity implements OnClickListener{

	private ListView messagesListView;
	private User friend;
	private String currentUsername;
	private ChatConversation conversation;
	private EditText messageEditText;
	private ChattingMessageAdapter adapter;
	private static ChattingActivity instance;

	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.activity_chatting);
		
		Button buttonSend = (Button) findViewById(R.id.send_button);
		buttonSend.setOnClickListener(this);
		
		ImageButton addFriend = (ImageButton) findViewById(R.id.add_as_friend);
		addFriend.setOnClickListener(this);
		
		ImageButton block = (ImageButton) findViewById(R.id.blacklisted);
		block.setOnClickListener(this);
		
		messagesListView = (ListView) findViewById(R.id.message_list);
		messageEditText = (EditText) findViewById(R.id.message_edit_text);
		controller = Controller.getInstance();
		instance = this;
		
		friend = (User) getIntent().getSerializableExtra(Friend.KIND);
		
		conversation = controller.getConversationByUser(friend);
		adapter = new ChattingMessageAdapter(this, conversation.getMessages());
		messagesListView.setAdapter(adapter);
		
		SimpleEntry<String,JSONObject> prefs = controller.getSessionInfo(this);
		currentUsername="";
		try {
			currentUsername = prefs.getValue().getString(User.USERNAME_NAME);
		} catch (Exception e) {
		}
		
		getWindow().setSoftInputMode(
			      WindowManager.LayoutParams.SOFT_INPUT_STATE_ALWAYS_HIDDEN);
	}
	
	/**
	 * Method to get the instance of the Chatting Activity since this class is a Singleton.
	 * 
	 * @return ChattingActivity The instance of the Chatting activity.
	 */
	public static ChattingActivity getInstance(){
		return instance;
	}
	
	@Override
	protected void onPause() {
		super.onPause();
		conversation.setIsActive(false);
	}
	
	@Override
	protected void onResume() {
		super.onResume();
		conversation.setIsActive(true);
		update();
	}
	
	@Override
	public void onClick(View v) {
		AsyncTask<Void, Void, JSONObject> task=null;
		switch(v.getId()){

			case R.id.send_button:
				//Send a message
				final Message message = new Message(currentUsername,
						friend.getUsername(),messageEditText.getText().toString());
				
				
				    task = new AsyncTask<Void, Void, JSONObject>() {
					
					@Override
					protected JSONObject doInBackground(Void... params) {
						Log.i(Constants.APP_NAME, "Message sending");
						return controller.sendMessage(ChattingActivity.this, message);
					}
					
					@Override
					protected void onPostExecute(JSONObject result) {
						super.onPostExecute(result);
						int code=Constants.CODE_ERROR;
						
						try {
							code=result.getInt(Constants.CODE_NAME);
						} catch (Exception e) {
							Log.e(Constants.APP_NAME, "Error to retrieve message code : " + e.toString());
						}
						
						switch (code) {
						case Message.CODE_SENDED:
							conversation.addMessage(message);
							adapter.notifyDataSetChanged();
							messageEditText.setText("");
							messagesListView.setSelection(messagesListView.getCount());
							
							InputMethodManager imm = (InputMethodManager)getSystemService(
								      Context.INPUT_METHOD_SERVICE);
							imm.hideSoftInputFromWindow(messageEditText.getWindowToken(), 0);
							break;
							
						case Message.CODE_DEST_UNAVAILABLE:
							Toast.makeText(ChattingActivity.this, getResources().getString(R.string.dest_unavailable), Toast.LENGTH_LONG).show();
							break;
							
						case Message.CODE_SESSION_INVALID:
							Toast.makeText(ChattingActivity.this, getResources().getString(R.string.invalid_session), Toast.LENGTH_LONG).show();
							Intent i = new Intent(ChattingActivity.this, LoginActivity.class);
							startActivity(i);
							break;
							
						case Message.CODE_CANT_SEND:
							Toast.makeText(ChattingActivity.this,
									getResources().getString(R.string.sending_error), Toast.LENGTH_LONG).show();
							break;
							
						case Message.CODE_BLACKLISTED:
							Toast.makeText(ChattingActivity.this,
									getResources().getString(R.string.blacklisted), Toast.LENGTH_LONG).show();
							controller.getResultList().remove(friend);
							
							Intent it = new Intent(ChattingActivity.this, HomeActivity.class);
							startActivity(it);
							break;
						}
					}
						
				};				
				break;
				
			case R.id.add_as_friend:
				//Add a friend
				task = new AsyncTask<Void, Void, JSONObject>() {
					
					@Override
					protected JSONObject doInBackground(Void... params) {
						JSONObject info = new JSONObject();
						try {
							info.put(Constants.ACTIONCODE_NAME, Constants.ADDFRIENDLINK);
							info.put(Constants.USERNAMELINK_NAME, currentUsername );
							info.put(Constants.TARGETNAMELINK_NAME, friend.getUsername());
						} catch (Exception e) {
							Log.e(Constants.APP_NAME, "Error to add friend management info : " + e.toString());
						}
						
						return controller.manageFriend(ChattingActivity.this, info);
					}
					
					protected void onPostExecute(JSONObject result) {
						int code = Constants.CODE_ERROR;
						try {
							code = result.getInt(Constants.CODE_NAME);
						} catch (Exception e) {
							Log.e(Constants.APP_NAME, "Error to manage friend : " + e.toString());
						}
						
						switch(code){
							case Constants.CODE_REQUESTVALID:
								Toast.makeText(ChattingActivity.this, getResources().getString(R.string.successful_add)
										, Toast.LENGTH_LONG).show();
								break;
								
							case Constants.CODE_ERROR:
								Toast.makeText(ChattingActivity.this, getResources().getString(R.string.error)
										, Toast.LENGTH_LONG).show();
								break;
						}
					};
				};
				break;
				
			case R.id.blacklisted :
				//Blacklist user
				task = new AsyncTask<Void, Void, JSONObject>() {
					
					@Override
					protected JSONObject doInBackground(Void... params) {
						JSONObject info = new JSONObject();
						try {
							info.put(Constants.ACTIONCODE_NAME, Constants.ADDBLACKLINK);
							info.put(Constants.USERNAMELINK_NAME,currentUsername );
							info.put(Constants.TARGETNAMELINK_NAME, friend.getUsername());
						} catch (Exception e) {
							Log.e(Constants.APP_NAME, "Error to add blacklist management info : " + e.toString());
						}
						
						return controller.manageFriend(ChattingActivity.this, info);
					}
					
					@Override
					protected void onPostExecute(JSONObject result) {
						super.onPostExecute(result);
						int code = Constants.CODE_ERROR;
						try {
							code = result.getInt(Constants.CODE_NAME);
						} catch (Exception e) {
							Log.e(Constants.APP_NAME, "Error to manage friend : " + e.toString());
						}
						
						switch(code){
							case Constants.CODE_REQUESTVALID:
								Toast.makeText(ChattingActivity.this, getResources().getString(R.string.successful_block)
										, Toast.LENGTH_LONG).show();
								break;
								
							case Constants.CODE_ERROR:
								Toast.makeText(ChattingActivity.this, getResources().getString(R.string.error)
										, Toast.LENGTH_LONG).show();
								break;
		
						}
					}
				};
		}
		
		if(Utils.hasConnectivity(this) && task!=null){
			if(messageEditText.getText().toString().isEmpty() && v.getId()==R.id.send_button){
				Toast.makeText(this, getResources().getString(R.string.empty_message), Toast.LENGTH_LONG).show();
			}else{
				task.execute();
			}	
		}else{
			Toast.makeText(this, getResources().getString(R.string.no_connectivity), Toast.LENGTH_LONG).show();
		}
	}
	
	/**
	 * Method to update adapter informations when a message is send or received.
	 */
	public void update(){
		adapter.notifyDataSetChanged();
	}
}
